#!/usr/bin/env python3
"""
RedFire User Service - 依赖管理脚本
================================

使用 pip-tools 管理项目依赖的自动化脚本
支持编译、同步、安全扫描等操作
"""

import argparse
import subprocess
import sys
from pathlib import Path
from typing import List, Optional


class DependencyManager:
    """依赖管理器"""
    
    def __init__(self, service_root: Path):
        self.service_root = service_root
        self.requirements_dir = service_root / "requirements"
        self.pip_tools_config = service_root / "pip-tools-config.txt"
        
    def run_command(self, cmd: List[str], check: bool = True) -> subprocess.CompletedProcess:
        """执行命令"""
        print(f"🔧 执行命令: {' '.join(cmd)}")
        try:
            result = subprocess.run(cmd, check=check, capture_output=True, text=True)
            if result.stdout:
                print(result.stdout)
            return result
        except subprocess.CalledProcessError as e:
            print(f"❌ 命令执行失败: {e}")
            if e.stderr:
                print(f"错误信息: {e.stderr}")
            if check:
                sys.exit(1)
            return e
    
    def install_pip_tools(self) -> None:
        """安装 pip-tools"""
        print("📦 检查并安装 pip-tools...")
        self.run_command([sys.executable, "-m", "pip", "install", "pip-tools>=7.3.0"])
        print("✅ pip-tools 安装完成")
    
    def compile_requirements(self, env: Optional[str] = None) -> None:
        """编译依赖文件"""
        print(f"🔨 编译依赖文件 (环境: {env or 'all'})")
        
        environments = ["base", "development", "testing", "production"] if not env else [env]
        
        for environment in environments:
            in_file = self.requirements_dir / f"{environment}.in"
            txt_file = self.requirements_dir / f"{environment}.txt"
            
            if not in_file.exists():
                print(f"⚠️  跳过 {environment}: {in_file} 不存在")
                continue
            
            cmd = [
                sys.executable, "-m", "piptools", "compile",
                "--config", str(self.pip_tools_config),
                "--output-file", str(txt_file),
                str(in_file)
            ]
            
            self.run_command(cmd)
            print(f"✅ {environment}.txt 编译完成")
    
    def sync_dependencies(self, env: str = "development") -> None:
        """同步依赖到当前环境"""
        print(f"🔄 同步 {env} 环境依赖...")
        
        req_file = self.requirements_dir / f"{env}.txt"
        if not req_file.exists():
            print(f"❌ 依赖文件不存在: {req_file}")
            print("请先运行: python scripts/manage_deps.py compile")
            sys.exit(1)
        
        cmd = [sys.executable, "-m", "piptools", "sync", str(req_file)]
        self.run_command(cmd)
        print(f"✅ {env} 环境依赖同步完成")
    
    def check_security(self) -> None:
        """检查依赖安全性"""
        print("🔒 检查依赖安全性...")
        
        # 安装 pip-audit 如果不存在
        try:
            subprocess.run([sys.executable, "-m", "pip", "show", "pip-audit"], 
                         check=True, capture_output=True)
        except subprocess.CalledProcessError:
            print("📦 安装 pip-audit...")
            self.run_command([sys.executable, "-m", "pip", "install", "pip-audit"])
        
        # 扫描所有依赖文件
        for req_file in self.requirements_dir.glob("*.txt"):
            if req_file.name.startswith("requirements-"):
                continue  # 跳过组合文件
                
            print(f"🔍 扫描 {req_file.name}...")
            cmd = [sys.executable, "-m", "pip_audit", "--requirement", str(req_file)]
            result = self.run_command(cmd, check=False)
            
            if result.returncode == 0:
                print(f"✅ {req_file.name} 安全检查通过")
            else:
                print(f"⚠️  {req_file.name} 发现安全问题")
    
    def upgrade_dependencies(self, package: Optional[str] = None) -> None:
        """升级依赖"""
        if package:
            print(f"📈 升级特定包: {package}")
            self.run_command([sys.executable, "-m", "pip", "install", "--upgrade", package])
        else:
            print("📈 升级所有依赖...")
            self.compile_requirements()
        
        print("✅ 依赖升级完成")
    
    def clean_dependencies(self) -> None:
        """清理依赖"""
        print("🧹 清理依赖缓存...")
        
        # 清理 pip 缓存
        self.run_command([sys.executable, "-m", "pip", "cache", "purge"])
        
        # 清理编译文件
        for txt_file in self.requirements_dir.glob("*.txt"):
            if txt_file.exists():
                print(f"🗑️  删除 {txt_file.name}")
                txt_file.unlink()
        
        print("✅ 清理完成")
    
    def show_outdated(self) -> None:
        """显示过时的依赖"""
        print("📊 检查过时的依赖...")
        self.run_command([sys.executable, "-m", "pip", "list", "--outdated"])


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="RedFire User Service 依赖管理工具")
    parser.add_argument("action", choices=[
        "install-tools", "compile", "sync", "security", 
        "upgrade", "clean", "outdated"
    ], help="要执行的操作")
    
    parser.add_argument("--env", choices=["base", "development", "testing", "production"],
                       help="指定环境")
    parser.add_argument("--package", help="指定要升级的包名")
    
    args = parser.parse_args()
    
    # 确定服务根目录
    script_path = Path(__file__).resolve()
    service_root = script_path.parent.parent
    
    manager = DependencyManager(service_root)
    
    try:
        if args.action == "install-tools":
            manager.install_pip_tools()
        elif args.action == "compile":
            manager.compile_requirements(args.env)
        elif args.action == "sync":
            env = args.env or "development"
            manager.sync_dependencies(env)
        elif args.action == "security":
            manager.check_security()
        elif args.action == "upgrade":
            manager.upgrade_dependencies(args.package)
        elif args.action == "clean":
            manager.clean_dependencies()
        elif args.action == "outdated":
            manager.show_outdated()
        
        print("🎉 操作完成!")
        
    except KeyboardInterrupt:
        print("\n⚠️  操作被用户中断")
        sys.exit(1)
    except Exception as e:
        print(f"❌ 执行失败: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
